package com.agan.net.knowledge;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.nio.ByteBuffer;

public class PlatformDependent {
    public static Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException {
        // 通过反射得到theUnsafe对应的Field对象
        Field field = Unsafe.class.getDeclaredField("theUnsafe");
        // 设置该Field为可访问
        field.setAccessible(true);
        // 在java的反射中,通过字段获取对象的方法： public Object get(Object obj)
        // 字段不是静态字段的话,要传入反射类的对象.如果传null是会报 java.lang.NullPointerException
        // 但是如果字段是静态字段的话,传入任何对象都是可以的,包括null
        Unsafe unsafe = (Unsafe) field.get(null);
        return unsafe;
    }

    public static void unsafeInstance() throws Exception {
        Unsafe unsafe = getUnsafe();
        //避开构造方法初始化对象，使用allocateInstance
        com.agan.net.knowledge.User instance = (User) unsafe.allocateInstance(User.class);
        //打印 User{id=0, name='null', age=0}
        System.out.println(instance);
    }

    public static void unsafeUpdate() throws Exception {
        Unsafe unsafe = getUnsafe();
        User user = new User();
        Class userClass = user.getClass();
        Field name = userClass.getDeclaredField("name");
        Field id = userClass.getDeclaredField("id");
        Field age = userClass.getDeclaredField("age");

        //直接往物理内存地址写数据
        unsafe.putObject(user, unsafe.objectFieldOffset(name), "阿甘001");
        unsafe.putLong(user, unsafe.objectFieldOffset(id), 10000L);
        unsafe.putInt(user, unsafe.objectFieldOffset(age), 100);

        //打印User{id=10000, name='阿甘001', age=100}
        System.out.println(user);
    }

    public static long allocateMemory(long bytes) throws NoSuchFieldException, IllegalAccessException {
        Unsafe unsafe = getUnsafe();
        long address= unsafe.allocateMemory(bytes);
        System.out.println(address);

        return address;
    }

    /**
     * 获取某个属性值
     */
    public static void getFieldValue() throws Exception {
        Unsafe unsafe = getUnsafe();
        User user = new User();
        Class userClass = user.getClass();
        Field id = userClass.getDeclaredField("id");

        //objectFieldOffset: 获取对象某个属性的地址偏移值
        long idOffset=unsafe.objectFieldOffset(id);
        long  idvalue=unsafe.getLong(user,idOffset);
        //打印结果 100
        System.out.println(idvalue);
    }

    public static void duplicateMemory() throws NoSuchFieldException, IllegalAccessException {
        ByteBuffer buffer=io.netty.util.internal.PlatformDependent.allocateDirectNoCleaner(1024*1024*16);
        buffer.put("aaa".getBytes());
        //buffer.flip();
        System.out.println(new String(buffer.array()));


    }


    public static void main(String[] args) throws Exception {
        User user = new User();
        //打印User{id=100, name='agan', age=18}
        System.out.println(user);

        unsafeInstance();
        unsafeUpdate();
        allocateMemory(1024L);

        getFieldValue();

        duplicateMemory();
    }
}
